package com.wyp168.juc.future;

import com.wyp168.juc.util.ExecutorsUtil;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName CompletableFutureDemo003
 * @Description 通过CompletableFuture类的 whenComplete 方法 及 exceptionally方法的链式编程方式
 *              可以直接使用前一个线程的运算结果，或者捕获前一个线程的异常信息，并处理
 *              TODO 注意：当没有指定线程池时，会默认使用 ForkJoinPool 线程池，该线程池会是一个守护线程，当main线程快于该线程执行结束
                该线程也会结束，无法继续执行，所以，建议使用自定义线程池的方式来使用 CompletableFuture 类
 * @Author wyp168
 * @Date 2022/9/11 17:55
 */
public class CompletableFutureDemo003 {
    public static void main(String[] args) {
        //通过工具类获取一个自定义线程池对象
        ThreadPoolExecutor threadPoolExecutor = ExecutorsUtil.getThreadPoolExecutor();
        try {
            CompletableFuture.supplyAsync(() -> {
                System.out.println(Thread.currentThread().getName());
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int result = ThreadLocalRandom.current().nextInt(10);
                return result;
            }, threadPoolExecutor).whenComplete((v, e) -> { //程序正常执行的分支入口（无异常）
                if (e == null) {
                    System.out.println("----获取到结果：" + v);
                }
            }).exceptionally(e -> { //上述程序有异常时的处理
                e.printStackTrace();
                System.out.println(e.getCause() + "\t" + e.getMessage());
                return null;
            });
        } finally {
            //关闭线程池
            threadPoolExecutor.shutdown();
        }

//        try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) {e.printStackTrace();}
        System.out.println(Thread.currentThread().getName() + " is over~");
    }
}
